#pragma once
#include <iostream>
#include <string>
#include <functional>
#include "InetAddr.hpp"

// 声明一下Reactor
class Reactor;

class Connection;
using handler_t = std::function<std::string(std::string &)>;

// 基类
//  封装fd，保证给每一个fd一套缓冲区
class Connection
{
public:
    Connection()
        : _events(0),
          _owner(nullptr)
    {
    }

    // 读取方法
    virtual void Recver() = 0;
    // 写入方法
    virtual void Sender() = 0;
    // 处理异常的方法
    virtual void Excepter() = 0;
    // 获取fd的方法
    virtual int GetSockFd() = 0;
    // 注册处理函数的方法，基类设为空，留给Channel子类重写
    void RegisterHandler(handler_t handler)
    {
        _handler = handler;
    }

    // 设置要关心事件的方法
    void SetEvent(const uint32_t &events)
    {
        _events = events;
    }

    // 返回要关心事件的集合
    uint32_t GetEvent()
    {
        return _events;
    }

    // 设置Reactor指针对象
    void SetOwner(Reactor *owner)
    {
        _owner = owner;
    }

    // 获取Reactor指针对象
    Reactor *GetOwner()
    {
        return _owner;
    }

    ~Connection() {}

private:
    // 该fd要关心的事件
    uint32_t _events;

    // 回指指针
    // 用来得到对应的Reactor指针对象（该Connection对象属于这个反应堆）
    // 方便在Listener类中使用方法来用这个Reactor指针对象
    // 调用AddConnection新增连接的方法来将其下面的新fd和Connection对象建立映射
    Reactor *_owner;

public:
    // 使用函数包装器来把我们的Channel对象带出去
    // 再写一个让上层传入进行Channel处理方法的函数
    handler_t _handler; // 基类中定义了一个回调函数
};